﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Office.Interop.Excel;

namespace WFL.Office.Excel
{
    public class ExcelWorksheet : DisposableSite, ISheet
    {
        private readonly object _lock = new object();

        public string Name
        {
            get { return _worksheet.Name; }
            set { _worksheet.Name = value; }
        }

        public RangeIndex Range
        {
            get;
            private set;
        }

        private ExcelRange _columns;
        public ExcelRange Columns
        {
            get
            {
                if (_columns == null)
                {
                    lock (_lock) { if (_columns == null) { _columns = new ExcelRange(_worksheet.Columns); } }
                }
                return _columns;
            }
        }

        private ExcelRange _cells;
        public ExcelRange Cells
        {
            get
            {
                if (_cells == null)
                {
                    lock (_lock) { if (_cells == null) { _cells = new ExcelRange(_worksheet.Cells); } }
                }
                return _cells;
            }
        }

        internal Worksheet _worksheet
        {
            get;
            private set;
        }

        private ExcelApplication _application;
        public ExcelApplication Application
        {
            get { return _application; }
            internal set { _application = value; }
        }

        internal ExcelWorksheet(Worksheet worksheet)
        {
            _worksheet = worksheet;
            Range = new RangeIndex(GetRange);
        }

        private ExcelRange GetRange(object cell1, object cell2)
        {
            ExcelRange item = new ExcelRange(_worksheet.get_Range(cell1, cell2 ?? Type.Missing)) { Application = Application };
            Trace(item);
            return item;
        }

        public void Select(object replace = null)
        {
            _worksheet.Select(replace ?? Type.Missing);
        }

        protected override void Dispose(bool disposing)
        {
            if (_worksheet != null)
            {
                if (disposing)
                {
                    ExcelRange columns = _columns;
                    if (columns != null)
                    {
                        _columns = null;
                        columns.Dispose();
                    }
                    ExcelRange cells = _cells;
                    if (cells != null)
                    {
                        _cells = null;
                        cells.Dispose();
                    }
                    Marshal.ReleaseComObject(_worksheet);
                }
                _worksheet = null;
                _application = null;
                base.Dispose(disposing);
            }
        }
    }
}
